<?php
/**
 * 组合模式
 * This file is part of pattern.
 * Author: tangzhou
 * Date: 2016/9/1
 * Time: 11:01
 * File: Combination.php
 */

abstract class Company
{
    protected $name;
    function __construct($name)
    {
        $this->name = $name;
    }

    abstract function Add(Company $company);
    abstract function remove(Company $company);
    abstract function display($depth);
}

class SubCompany extends Company
{
    private $subCompany;

    function __construct($name)
    {
        parent::__construct($name);
    }

    function Add(Company $company)
    {
        $this->subCompany[] = $company;
    }

    function remove(Company $company)
    {
        $key = array_search($company, $this->subCompany);
        if ($key !== false) {
            unset($this->subCompany[$key]);
        }
    }

    function display($depth)
    {
        $pre = "";
        for ($i = 0; $i < $depth; $i++) {
            $pre .= "-";
        }
        $pre .= $this->name . "<br/>";
        echo $pre;

        foreach ($this->subCompany as $v) {
            $v->display($depth + 2);
        }
    }
}

/**叶子节点  财务部
 * Class DeptCompany
 */
class MoneyDept extends Company
{

    function __construct($name)
    {
        parent::__construct($name);
    }

    /**增加
     * @param Company $company 子公司，部门
     * @return mixed
     */
    function Add(Company $company)
    {
        echo "叶子节点，不能继续添加节点。。。。。。。。。。<br/>";
    }

    /**移除
     * @param Company $company 子公司，部门
     * @return mixed
     */
    function Remove(Company $company)
    {
        echo "叶子节点，不能删除节点。。。。。。。。。。<br/>";
    }

    /**显示公司及部门结构
     * @param $depth
     * @return mixed
     */
    function Display($depth)
    {
        $pre="";
        for($i=0;$i<$depth;$i++)
        {
            $pre.="-";
        }
        $pre.=$this->name."<br/>";
        echo $pre;
    }
}


/**叶子节点  技术
 * Class DeptCompany
 */
class TechnologyDept extends Company
{

    function __construct($name)
    {
        parent::__construct($name);
    }

    /**增加
     * @param Company $company 子公司，部门
     * @return mixed
     */
    function Add(Company $company)
    {
        echo "叶子节点，不能继续添加节点。。。。。。。。。。<br/>";
    }

    /**移除
     * @param Company $company 子公司，部门
     * @return mixed
     */
    function Remove(Company $company)
    {
        echo "叶子节点，不能删除节点。。。。。。。。。。<br/>";
    }

    /**显示公司及部门结构
     * @param $depth
     * @return mixed
     */
    function Display($depth)
    {
        $pre="";
        for($i=0;$i<$depth;$i++)
        {
            $pre.="-";
        }
        $pre.=$this->name."<br/>";
        echo $pre;
    }
}

$root=new SubCompany("北京总公司");
$root->Add(new MoneyDept("总公司财务部"));
$root->Add(new TechnologyDept("总公司技术部"));

$shanghai=new SubCompany("上海分公司");
$shanghai->Add(new TechnologyDept("上海分公司技术部"));
$shanghai->Add(new MoneyDept("上海分公司财务部"));

$root->Add($shanghai);

$root->display(1);

echo "<hr/>";

$root->remove($shanghai);
$root->display(3);
